package com.tuo51.evaluate.controller;


import com.alibaba.fastjson.JSON;
import com.tuo51.core.domain.org.Organization;
import com.tuo51.core.domain.staffs.Staff;
import com.tuo51.core.service.StaffService;
import com.tuo51.evaluate.domain.childrens.Children;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Item;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Question;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Record;
import com.tuo51.evaluate.domain.evaluatingV2.EvaluateV2Tool;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2ItemRepository;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2QuestionRepository;
import com.tuo51.evaluate.repositories.evaluatev2.EvaluateV2ToolRepository;
import com.tuo51.evaluate.service.ChildrenService;
import com.tuo51.evaluate.service.EvaluateV2ConclusionService;
import com.tuo51.evaluate.service.EvaluateV2ExportService;
import com.tuo51.evaluate.service.EvaluateV2Service;
import com.tuo51.evaluate.vo.children.ChildrenVO;
import com.tuo51.evaluate.vo.children.NewEvaluatePO;
import com.tuo51.evaluate.vo.evaluate.*;
import com.tuo51.foudation.constant.RequestConstant;
import com.tuo51.foudation.exception.BusinessException;
import com.tuo51.foudation.model.ErrorCode;
import com.tuo51.foudation.model.MemVerificationCache;
import com.tuo51.foudation.model.StatusResponse;
import com.tuo51.foudation.query.EvaluateQuery;
import com.tuo51.foudation.utils.CopyUtils;
import com.tuo51.foudation.utils.DateUtil;
import com.tuo51.foudation.utils.QrCodeUtils;
import com.tuo51.manager.vo.EvaluateV2QuestionVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

import static com.tuo51.foudation.constant.RequestConstant.APP_CHANNEL;
import static com.tuo51.foudation.constant.RequestConstant.TICKET;
import static com.tuo51.foudation.model.ErrorCode.BIRTHDAY_BEGGER_THAN_TODAY;
import static com.tuo51.foudation.model.ErrorCode.DATE_FORMAT_ERROR;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * 测评小程序使用的接口
 */

@RestController
@RequestMapping("/eapi/operator")
@Api(value = "/eapi/operator", tags = "测评 - 测评师操作")
public class EvaluatePBOperatorController {

    @Autowired
    private EvaluateV2Service evaluateService;

    @Autowired
    private EvaluateV2QuestionRepository questionRepository;

    @Autowired
    private EvaluateV2ToolRepository toolRepository;

    @Autowired
    private EvaluateV2ConclusionService conclusionService;

    @Autowired
    private MemVerificationCache cache;

    @Autowired
    private ChildrenService childrenService;

    @Autowired
    private StaffService staffService;

    @Autowired
    private EvaluateV2ExportService exportService;

    @Autowired
    private EvaluateV2ItemRepository itemRepository;

    @Value("${export.pb.share_url_ma}")
    private String exportShareURLMA;

    @Value("${export.pb.share_url_mp}")
    private String exportShareURLMP;

    @Value("${export.pb.guide_url_mp}")
    private String exportShareURLGuide;


    @RequestMapping(value = "/children", method = POST)
    public StatusResponse getChildren(@RequestHeader(TICKET) String ticket,
                                      String orderBy){

        return childrenByName(ticket, null, orderBy);

    }

    @RequestMapping(value = "/children_by_name", method = POST)
    @ApiOperation("查询宝宝列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名字，支持模糊搜索"),
            @ApiImplicitParam(name = "orderBy", value = "排序， created， next， last， birthday"),
            @ApiImplicitParam(name = "ticket", value = "票据", paramType = "header", required = false)

    })
    public StatusResponse childrenByName(@RequestHeader(TICKET) String ticket, String name, String orderBy){
        List<EvaluateChildrenVO> evaluateChildrenVOS = null;
        if(StringUtils.isBlank(name)) {
            evaluateChildrenVOS = evaluateService.getChildrenEvaluateInfo(cache.getStaffId(ticket), orderBy);
        }else{
            evaluateChildrenVOS = evaluateService.getChildrenByNameEvaluate(cache.getStaffId(ticket), name, orderBy);
        }

        return StatusResponse.success(evaluateChildrenVOS);
    }

    @RequestMapping(value = "/children_detail", method = POST)
    public StatusResponse childrenDetail(@RequestHeader(TICKET) String ticket, String childrenId){
        String staffId = cache.getStaffId(ticket);

        Children c = childrenService.getById(childrenId, staffId);
        if(c == null){
            throw new BusinessException(ErrorCode.CHILDREN_NOT_EXIST, "宝宝不存在");
        }

        c.setMonth(DateUtil.betweenMonths(new Date(), c.getBirthday()));

        ChildrenVO ret = ChildrenVO.of(c);

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/delete_children", method = POST)
    public StatusResponse deleteChildren(@RequestHeader(TICKET) String ticket, String childrenId) {
        String staffId = cache.getStaffId(ticket);

        boolean ret = childrenService.deleteChildrenForStaff(childrenId, staffId);

        return StatusResponse.success(ret);
    }

    @ApiOperation(value = "宝宝测评列表",httpMethod = "POST")
    @RequestMapping("/children_reports")
    public StatusResponse childrenEvaluatePage(@RequestHeader(TICKET) String ticket, EvaluateQuery query) {
        query.validateOrderByAndSequence();

        String staffId = cache.getStaffId(ticket);
        query.setStaffId(staffId);

        Page<WebEvaluateRecordListVo> recordPage = evaluateService.getEvaluatePage(query);

        return StatusResponse.success(recordPage);
    }

    @ApiOperation(value = "测评列表",httpMethod = "POST")
    @RequestMapping("/reports")
    public StatusResponse evaluatePage(@RequestHeader(TICKET) String ticket, EvaluateQuery query) {
        query.validateOrderByAndSequence();

        String staffId = cache.getStaffId(ticket);
        query.setStaffId(staffId);

        Page<WebEvaluateRecordListVo> recordPage = evaluateService.getEvaluatePage(query);

        return StatusResponse.success(recordPage);
    }


    @ApiOperation(value = "测评列表",httpMethod = "POST")
    @RequestMapping("/reportsNoTicket")
    public StatusResponse evaluatePage(EvaluateQuery query) {
        query.validateOrderByAndSequence();

//        String staffId = cache.getStaffId(ticket);
//        query.setStaffId(staffId);

        Page<WebEvaluateRecordListVo> recordPage = evaluateService.getEvaluatePage1(query);

        return StatusResponse.success(recordPage);
    }

    @ApiOperation(value = "测评列表",httpMethod = "POST")
    @PostMapping("/reportsApi")
    public StatusResponse evaluatePageApi(@RequestBody EvaluateQuery query) {
        query.validateOrderByAndSequence();

//        String staffId = cache.getStaffId(ticket);
//        query.setStaffId(staffId);

        Page<WebEvaluateRecordListVo> recordPage = evaluateService.getEvaluatePage2(query);

        return StatusResponse.success(recordPage);
    }


    @RequestMapping(value = "/next_evaluate_item", method = POST)
    public StatusResponse nextEvaluateItemByRecordId(@RequestHeader(TICKET) String ticket, String recordId,
                                                     @RequestParam(required = false, defaultValue = "false") boolean resume,
                                                     String questionIdsStr, String checkedsStr ){
        String[] questionIds = null;
        boolean[] cs = null;

        //用checkedStr来处理答案
        if(questionIdsStr != null && checkedsStr != null) {
            String[] checkeds = checkedsStr.split("\\|");
            questionIds = questionIdsStr.split("\\|");

            if (questionIds.length != checkeds.length) {
                return StatusResponse.error(DATE_FORMAT_ERROR, "bad params");
            }

            if(questionIds.length > 0){
                cs =  new boolean[questionIds.length];
                for(int i = 0 ; i < cs.length; i++){
                    cs[i] = Boolean.parseBoolean(checkeds[i]);
                }
            }
        }


        EvaluateV2Item ret = evaluateService.nextEvaluateItem(recordId, questionIds, cs, resume );

        if(ret == null){
            finishEvaluate(ticket, recordId);
        }else{
            disableNonVIPGuideVideo(ticket, ret);
        }

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/next_evaluate_item_v2", method = POST)
    public StatusResponse nextEvaluateItemByRecordIdV2(@RequestHeader(TICKET) String ticket,
                                                       @RequestHeader(value = APP_CHANNEL, required = false) String channel,
                                                       String recordId,
                                                       @RequestParam(required = false, defaultValue = "false") boolean resume,
                                                       @RequestParam(required = false) String currentQuestionIds,
                                                       @RequestParam(required = false) String options){


        String[] questionIds = null;
        boolean[] cs = null;

        if(StringUtils.isNotEmpty(currentQuestionIds)){
            questionIds = currentQuestionIds.split("\\|") ;
            cs = (questionIds != null && questionIds.length > 0) ? new boolean[questionIds.length] : null;

            //当期缓存
            Map cache = evaluateService.cacheAnswerForEvaluateItem(recordId, options);

            for (int i = 0; i < questionIds.length; i++){
                String qId = questionIds[i];
                String checked = (String) cache.get(qId);
                cs[i] =  Boolean.parseBoolean(checked);
            }
        }

        EvaluateV2Item ret = evaluateService.nextEvaluateItem(recordId, questionIds, cs, resume );
        if(ret == null){
            this.finishEvaluate(ticket, recordId);
        }else{
            //所有的都已经有缓存答案了，换下一个item
            while (ret != null && !evaluateService.anyQuestionInItemNotChecked(recordId, ret)) {
                //填入临时的答案
                int length = ret.getQuestions().size() > 0 ? ret.getQuestions().size() : 3 ;
                questionIds = new String[length];
                cs = new boolean[length];

                for (int i = 0; i < ret.getQuestions().size(); i++){
                    EvaluateV2Question question = ret.getQuestions().get(i);

                    questionIds[i] = question.getId();
                    cs[i] = question.getChecked();
                }

                ret = evaluateService.nextEvaluateItem(recordId, questionIds, cs, false);
            }

            if(ret == null){
                this.finishEvaluate(ticket, recordId);
                return StatusResponse.success(ret);
            }

            //非VIP禁用视频
            if(!"bbdcp".equals(channel)) {
                disableNonVIPGuideVideo(ticket, ret);
            }
        }

        if (ret != null){
            List<EvaluateV2Question> questions = ret.getQuestions();
            if (questions == null){
                questionRepository.findAllByItemIdAndDeletedIsFalseOrderByIndexOnPaper(ret.getId());
            }

            
            List<EvaluateV2QuestionVO> qvos = null;

            if (questions != null) {
                qvos = questions.stream().map(k ->{
                    EvaluateV2QuestionVO qvo = EvaluateV2QuestionVO.ofWithoutTools(k);

                    //不知道为什么 lazy 模式没有加载。
                    List<EvaluateV2Tool> tools = toolRepository.findAllByQuestionIdAndDeletedIsFalse(k.getId());
                    qvo.setTools(tools.stream().map(t->EvaluateV2ToolVO.of(t)).collect(Collectors.toList()));

                    return qvo;
                }).collect(Collectors.toList());
            }

            EvaluateV2ItemVO result = EvaluateV2ItemVO.of(ret, qvos);
            return StatusResponse.success(result);
        }

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/next_dimension", method = POST)
    public StatusResponse nextDimension(@RequestHeader(TICKET) String ticket,
                                        @RequestHeader(APP_CHANNEL) String channel,
                                        String recordId,
                                        @RequestParam String itemId){


        //当前测评item
        EvaluateV2Item curItem = itemRepository.findTop1ByIdAndDeletedIsFalse(itemId);
        if(curItem == null){
            throw new BusinessException(ErrorCode.VERSION_ERROR, "指定测评单元不存在");
        }
        List<EvaluateV2Question> questions = questionRepository.findAllByItemIdAndDeletedIsFalseOrderByIndexOnPaper(itemId);
        String currentQuestionIds = questions.stream().map(q->q.getId()).collect(Collectors.joining("|"));
        Map opsMap = questions.stream().collect(Collectors.toMap(EvaluateV2Question::getId, q->false));
        String options = JSON.toJSONString(opsMap);

        //构造新的接口请求
        StatusResponse response = nextEvaluateItemByRecordIdV2(ticket, channel, recordId, false, currentQuestionIds, options);

        //当前测评维度
        String dimensionId = curItem.getDimensionId();

        //
        Object ret = response.getData();
        if (ret == null){
            return response;
        }

        Map result = CopyUtils.transBean2Map(ret);
        String newDid = (String) result.get("dimensionId");
        String newItemId = (String)result.get("id");
        if (StringUtils.isBlank(newDid)){
            return response;
        }

        while (StringUtils.isNotBlank(newDid) && newDid.equals(dimensionId)){
            //下一个
            //准备这个节点的题目id；
            questions = questionRepository.findAllByItemIdAndDeletedIsFalseOrderByIndexOnPaper(newItemId);
            if (questions == null || questions.size() == 0){
                //为啥没有题目了?
                break;
            }

            currentQuestionIds = questions.stream().map(q->q.getId()).collect(Collectors.joining("|"));

            //构造答题卡
            opsMap = questions.stream().collect(Collectors.toMap(EvaluateV2Question::getId, q->false));
            options = JSON.toJSONString(opsMap);

            //获取下一个
            response = nextEvaluateItemByRecordIdV2(ticket, channel, recordId, false, currentQuestionIds, options);

            //分析是否到下一个维度了
            ret = response.getData();
            if (ret == null){
                return response;
            }

            result = CopyUtils.transBean2Map(ret);
            newDid = (String) result.get("dimensionId");
            newItemId = (String)result.get("id");
        }

        return response;
    }


    @Value("${tuo51.needvip.videoGuide}")
    private String needVipVideoGuide;
    private void disableNonVIPGuideVideo(String ticket, EvaluateV2Item item){
        //非年费会员，屏蔽掉视频指导
        Staff staff = cache.getStaff(ticket);
        if(staffService.isYearsVip(staff)){
            return;
        }

        for (EvaluateV2Question q : item.getQuestions()){
            q.setGuideVideo(needVipVideoGuide);
        }
    }

    @RequestMapping(value = "/draft_evaluate", method = POST)
    public StatusResponse draftEvaluate(@RequestHeader(TICKET) String ticket, String childrenName, String childrenId){
        String staffId = cache.getStaffId(ticket);

        EvaluateV2Record ret = evaluateService.draftEvaluateItemLastNotFinished(staffId, childrenId, childrenName);

        return StatusResponse.success(ret);
    }

    @ApiOperation("更新宝宝信息，所有字段可选")
    @RequestMapping(value = "/update_child_info", method = POST)
    public StatusResponse updateChildInfo(@RequestHeader(TICKET) String ticket,
                                          String childrenId,
                                          String childrenName,
                                          String nickName,
                                          String avatar,
                                          Integer gender,
                                          String birthday,
                                          String guardianPhone, String guardianName, String guardianRelation,
                                          String weight,
                                          String height,
                                          String header,
                                          String address,
                                          String remark){

        String staffId = cache.getStaffId(ticket);

        if (StringUtils.isEmpty(childrenId)){
            throw new BusinessException(ErrorCode.CHILDREN_NOT_EXIST, "宝宝不存在");
        }

        Children children = childrenService.getById(childrenId, staffId);
        if (children == null){
            throw new BusinessException(ErrorCode.CHILDREN_NOT_EXIST, "宝宝不存在");
        }

        children = childrenService.edit(children, childrenName, nickName, avatar, guardianPhone,guardianName, guardianRelation,
                birthday, gender, weight, height, header, address, remark);

        return StatusResponse.success(children);

    }

    private void assertWeightHeightHeader(String weight, String height, String header){
        try {
            if (StringUtils.isNotBlank(weight)) {
                Double.parseDouble(weight);
            }
            if (StringUtils.isNotBlank(height)) {
                Double.parseDouble(height);
            }
            if (StringUtils.isNotBlank(header)) {
                Double.parseDouble(header);
            }
        }catch (NumberFormatException e){
            throw  new BusinessException(ErrorCode.PARAM_NOT_BLANK, "身高体重头围格式错误");
        }
    }

    @ApiOperation("给新宝宝创建评测报告记录")
    @RequestMapping(value = "/add_evaluate_for_new", method = POST)
    public StatusResponse addEvaluate(@RequestHeader(TICKET) String ticket,
                                      String childAvatarUrl,
                                      String childrenName,
                                      String nickName,
                                      Integer gender,
                                      String birthday,
                                      String guardianPhone, String guardianName, String guardianRelation,
                                      String weight, String height, boolean skipWarningDiemnsion,
                                      @RequestParam(name = "demo", defaultValue = "0") Integer demo){

        String staffId = cache.getStaffId(ticket);

        assertWeightHeightHeader(weight, height, null);

        Children children = childrenService.add(staffId, childAvatarUrl,childrenName, nickName, gender,
                birthday, weight, height, guardianPhone, guardianName, guardianRelation);

        EvaluateV2Record record = evaluateService.startEvaluate(cache.getStaffId(ticket), children, weight, height, skipWarningDiemnsion, demo,guardianPhone,guardianRelation );

        EvaluateV2RecordVO result = EvaluateV2RecordVO.of(record);

        return StatusResponse.success(result);

    }

    @ApiOperation("给指定的宝宝追加测评记录")
    @RequestMapping(value = "/add_evaluate", method = POST)
    public StatusResponse addEvaluate(@RequestHeader(TICKET) String ticket, String childrenId,
                                      String weight, String height,
                                      String avatar,
                                      String guardianPhone, String guardianName, String guardianRelation,
                                      boolean skipWarningDiemnsion,
                                      @RequestParam(name = "demo", defaultValue = "0") Integer demo){

        String staffId = cache.getStaffId(ticket);

        assertWeightHeightHeader(weight, height, null);

        Children children = childrenService.getById(childrenId, staffId);
        if (children == null){
            throw new BusinessException(ErrorCode.CHILDREN_NOT_EXIST, "宝宝不存在");
        }
        children = childrenService.edit(children, null, null, avatar, guardianPhone,guardianName, guardianRelation,
                null, null, weight, height, null, null, null);

        EvaluateV2Record record = evaluateService.startEvaluate(staffId, children, weight, height, skipWarningDiemnsion, demo ,guardianPhone,guardianRelation);

        EvaluateV2RecordVO result = EvaluateV2RecordVO.of(record);

        return StatusResponse.success(result);
    }


    @ApiOperation("直接增加一个新的报告")
    @RequestMapping(value = "/add_evaluate_immediately", method = POST)
    public StatusResponse createEvaluateReport(@RequestHeader(TICKET) String ticket,
                                               NewEvaluatePO po,
                                               String answers,
                                               String skipDimensions,
                                               String evaluateType,
                                               Long duration){

        String staffId = cache.getStaffId(ticket);

        //处理对象

        List<EvaluateV2SheetAnswerPO> answerList = JSON.parseArray( answers, EvaluateV2SheetAnswerPO.class);
        List<String> skipDimensionIds = JSON.parseArray(skipDimensions, String.class);

        assertWeightHeightHeader(po.getWeight(), po.getHeight(), po.getHeader());

        Children children = null;
        if (StringUtils.isNotEmpty(po.getChildrenId())){
            children = childrenService.getById(po.getChildrenId(), staffId);
            if (children == null){
                throw new BusinessException(ErrorCode.CHILDREN_NOT_EXIST, "宝宝不存在");
            }
            children = childrenService.edit(children, null, null,
                    po.getChildAvatarUrl(),
                    po.getGuardianPhone(), po.getGuardianName(), po.getGuardianRelation(),
                    null, null,
                    po.getWeight(), po.getHeight(), po.getHeader(),
                    null, null);
        }else{
            children = childrenService.add(staffId, po.getChildAvatarUrl(), po.getChildrenName(), po.getNickName(), po.getGender(),
                    po.getBirthday(), po.getWeight(), po.getHeight(),po.getGuardianPhone(), po.getGuardianName(), po.getGuardianRelation());
        }

        if (StringUtils.isEmpty(evaluateType)){
            evaluateType = "normal";
        }

        EvaluateV2Record record = evaluateService.createEvaluate(evaluateType, staffId, children,
                po.getWeight(), po.getHeight(), answerList,
                skipDimensionIds, duration ,po.getGuardianPhone(),po.getGuardianRelation());

        EvaluateV2Record object = evaluateService.getEvaluateDetail(record.getId());

        Map result = conclusionService.generateReportExtInfo(object);

        result.putAll(CopyUtils.transBean2Map(object));

        return StatusResponse.success(result);
    }
    @RequestMapping(value = "/full_dimensions", method = POST)
    public StatusResponse fullDimensions(@RequestHeader(TICKET) String ticket, boolean skipWarningDiemnsion){
        String staffId = cache.getStaffId(ticket);
        return StatusResponse.success(evaluateService.allValidEvaluatedDimension(skipWarningDiemnsion));
    }

    @RequestMapping(value = "/full_evaluate_items", method = POST)
    public StatusResponse fullEvaluateItems(@RequestHeader(TICKET) String ticket,
                                            String birthday,
                                            String dimensionId){
        String staffId = cache.getStaffId(ticket);

        List<EvaluateV2ItemVO> items = evaluateService.fullEvaluateItems(dimensionId, DateUtil.parseToDate(birthday));

        return StatusResponse.success(items);
    }

    @RequestMapping(value = "/evaluateChildrenInfo", method = POST)
    public StatusResponse evaluateChildrenInfo(@RequestHeader(TICKET) String ticket, String childrenId){
        Date today = new Date();
        Map map = new HashMap();

        String staffId = cache.getStaffId(ticket);

        try {
            Children children = childrenService.getById(childrenId, staffId);

            String birthday = DateUtil.formatDayToStr(children.getBirthday());

            if (DateUtil.parseToDate(birthday).compareTo(today) >= 0) {
                throw new BusinessException(BIRTHDAY_BEGGER_THAN_TODAY, "生日不能大于当前日期");
            }

            List<EvaluateV2Record> evaluateRecordList = evaluateService.getEvaluateRecordByChildrenId(childrenId);//宝贝历史测评记录

            int evaluateCount = evaluateRecordList.size();

            Integer month = DateUtil.betweenMonths(DateUtil.millisToDateTime(today.getTime(), "yyyy-MM-dd"), birthday);//月龄

            map.put("children", children);
            map.put("month", month);
            map.put("evaluateCount", evaluateCount);
            map.put("evaluateRecordList", evaluateRecordList);
        } catch (ParseException e) {
            throw new BusinessException(DATE_FORMAT_ERROR, "日期格式错误");
        }

        return StatusResponse.success(map);
    }

    @RequestMapping(value = "/question", method = GET)
    public StatusResponse questionById(@RequestHeader(TICKET) String ticket, String questionId){
        EvaluateV2Question question = evaluateService.getQuestionDetail(questionId);

        EvaluateV2QuestionVO ret = EvaluateV2QuestionVO.of(question);

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/full_evaluate_tools", method = POST)
    public StatusResponse fullEvaluateTools(@RequestHeader(TICKET) String ticket,
                                            Integer month, String birthday){
        if (StringUtils.isNotEmpty(birthday)){
            month = DateUtil.betweenMonths(new Date(), DateUtil.parseToDate(birthday));
        }

        List<EvaluateV2ToolVO> tools = evaluateService.getFullEvaluateTools(month);

        return StatusResponse.success(tools);
    }

    @RequestMapping(value = "/evaluate_tools_for_question", method = POST)
    public StatusResponse evaluateToolsByQuestionId(@RequestHeader(TICKET) String ticket, String questionId){
        List<EvaluateV2Tool> tools = evaluateService.getEvaluateToolsForQuestion(questionId);
        return StatusResponse.success(tools);
    }

    @RequestMapping(value = "/evaluate_tools_for_item", method = POST)
    public StatusResponse evaluateToolsByChildrenId(@RequestHeader(TICKET) String ticket, String itemId){
        List<EvaluateV2Tool> tools = evaluateService.getEvaluateToolsForItem(itemId);
        return StatusResponse.success(tools);
    }

    @RequestMapping(value = "/delete_report", method = POST)
    public StatusResponse deleteReport(@RequestHeader(TICKET) String ticket, String evaluateRecordId) {
        String staffId = cache.getStaffId(ticket);

        boolean ret = evaluateService.deleteReportForStaff(evaluateRecordId, staffId);

        return StatusResponse.success(ret);
    }

    @RequestMapping(value = "/detail", method = POST)
    public StatusResponse evaluateDetail(@RequestHeader(TICKET) String ticket,
                                         String evaluateRecordId,
                                         @RequestHeader(value = APP_CHANNEL, required = false) String channel) {
        String staffId = cache.getStaffId(ticket);

        Staff staff = staffService.getById(staffId);

        EvaluateV2Record object = evaluateService.getEvaluateDetail(evaluateRecordId,  channel);

        if(!object.getPaid()){
            //检查vip状态
            if(staffService.isYearsVip(staff)){
                EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId, true);
                object = evaluateRecord;
            }
        }
        object.setPaid(true);
        Map result = conclusionService.generateReportExtInfo(object);

        result.putAll(CopyUtils.transBean2Map(object));

        return StatusResponse.success(result);
    }




    @RequestMapping(value = "/detail1", method = POST)
    public StatusResponse evaluateDetail1(
                                         String evaluateRecordId,
                                         @RequestHeader(value = APP_CHANNEL, required = false) String channel) {

        EvaluateV2Record object = evaluateService.getEvaluateDetail(evaluateRecordId,  channel);

        if(!object.getPaid()){
            //检查vip状态
            if(true){
                EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId, true);
                object = evaluateRecord;
            }
        }

        Map result = conclusionService.generateReportExtInfo(object);

        result.putAll(CopyUtils.transBean2Map(object));

        return StatusResponse.success(result);
    }


    @PostMapping(value = "/detail2")
    public StatusResponse evaluateDetail2(
            @RequestBody EvaluateV2Record record,
            @RequestHeader(value = APP_CHANNEL, required = false) String channel) {

        EvaluateV2Record object = evaluateService.getEvaluateDetail(record.getId(),  channel);

        if(!object.getPaid()){
            //检查vip状态
            if(true){
                EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(record.getId(), true);
                object = evaluateRecord;
            }
        }
        object.setPaid(true);

        Map result = conclusionService.generateReportExtInfo(object);

        result.putAll(CopyUtils.transBean2Map(object));

        return StatusResponse.success(result);
    }





    @RequestMapping(value = "/compare_with", method = POST)
    public StatusResponse compareWithReport(@RequestHeader(TICKET) String ticket,
                                            @RequestParam("evaluateRecordId") String evaluateRecordId,
                                            @RequestParam("comparingWithId") String comparingWithId) {

        if(evaluateRecordId.equals(comparingWithId)){
            throw new BusinessException(ErrorCode.EVALUATE_NO_MATCH, "被比较报告不能是当前报告。");
        }

        Staff staff = cache.getStaff(ticket);

        //检查vip状态
        staffService.isYearsVipOrException(staff);

        EvaluateV2Record record = evaluateService.getEvaluateDetailForStaff(evaluateRecordId, staff.getId(), false);
        EvaluateV2Record comparing = evaluateService.getEvaluateDetailForStaff(comparingWithId, staff.getId(),false);

        int compare = comparing.getEvaluatingDate().compareTo(record.getEvaluatingDate());
        if(compare > 0){
            EvaluateV2Record r = record;
            record = comparing;
            comparing = r;
        }

        Map result = conclusionService.generateReportExtInfo(record);

        result.putAll(CopyUtils.transBean2Map(record));
        result.put("compareWith", comparing);
        result.put("compareDQConclusion", conclusionService.getDQComparingConclusion(record, comparing));
        result.put("compareWeightConclusion", conclusionService.getWeightComparingConclusion(record, comparing));
        result.put("compareHeightConclusion", conclusionService.getHeightComparingConclusion(record, comparing));

        return StatusResponse.success(result);
    }

    @RequestMapping(value = "/children_last_evaluate", method = POST)
    public StatusResponse questionRecordsByChildrenId(@RequestHeader(TICKET) String ticket,
                                                      String childrenId) {
        return StatusResponse.success(evaluateService.getLastEvaluateRecord(childrenId));
    }

    /**
     * 完成测评
     *
     * @param evaluateRecordId 测评纪录id
     * @return
     */
    @ApiOperation(value = "测评完成",httpMethod = "POST")
    @RequestMapping(value = "/finish_evaluate")
    public StatusResponse finishEvaluate(@RequestHeader(TICKET) String ticket, String evaluateRecordId) {

        String staffId = cache.getStaffId(ticket);

        Staff staff = staffService.getById(staffId);

        if(staffService.isYearsVip(staff)){
            EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId, true);
            return StatusResponse.success(evaluateRecord.getPublished());
        }else {
            Organization org = staffService.staffOrgnization(staff);
            if(Objects.nonNull(org.getRestCount()) && org.getRestCount() > 0){
                EvaluateV2Record evaluateRecord = evaluateService.finishEvaluateWithTimes(evaluateRecordId,org);
                return StatusResponse.success(evaluateRecord.getPublished());
            }else{
                EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId,false);
                return StatusResponse.success(evaluateRecord.getPublished());
            }
        }
    }



    /**
     * 完成测评
     *
     * @param evaluateRecordId 测评纪录id
     * @return
     */
    @ApiOperation(value = "测评完成",httpMethod = "POST")
    @RequestMapping(value = "/finish_evaluate1")
    public StatusResponse finishEvaluate(String evaluateRecordId) {

        if(true) {
            EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId, true);
            return StatusResponse.success(evaluateRecord.getPublished());
        }else {
            EvaluateV2Record evaluateRecord = evaluateService.finishEvaluate(evaluateRecordId,false);
            return StatusResponse.success(evaluateRecord.getPublished());
        }
    }



    @ApiOperation(value = "提醒家长做测评",httpMethod = "POST")
    @RequestMapping(value = "/notify_parent_to_evaluate")
    public StatusResponse notifyParentToEvaluate(@RequestHeader(TICKET) String ticket, String childrenId) {

        String staffId = cache.getStaffId(ticket);

        Staff staff = staffService.getById(staffId);

        staffService.isYearsVipOrException(staff);

        evaluateService.notifyParentToEvaluate(staffId, childrenId);

        return StatusResponse.success();
    }

    /**
     * 推送到家长时间轴
     *
     * @param evaluateRecordId 测评纪录id
     * @return
     */
    @ApiOperation(value = "推送给家长",httpMethod = "POST")
    @RequestMapping(value = "/grant_parent")
    public StatusResponse grantParentEvaluate(@RequestHeader(TICKET) String ticket, String evaluateRecordId) {

        String staffId = cache.getStaffId(ticket);

        Staff staff = staffService.getById(staffId);

        staffService.isYearsVipOrException(staff);

        EvaluateV2Record record = evaluateService.getEvaluateDetail(evaluateRecordId);
        if(record == null){
            throw  new BusinessException(ErrorCode.EVALUATE_RECORD_NOT_EXIST, "报告不存在");
        }
//        if(!record.getPaid() ){
//            throw  new BusinessException(ErrorCode.REPORT_PAID_NEEDED, "报告没有付费，无法推送给家长");
//        }
        if(record.getParentGranted()){
            throw new BusinessException(ErrorCode.VERSION_ERROR, "已经推送给家长了");
        }

        evaluateService.grantEvaluateToParent(staff, record);

        return StatusResponse.success();
    }

    /**
     * 推送到家长时间轴
     *
     * @param evaluateRecordId 测评纪录id
     * @return
     */
    @ApiOperation(value = "取消推送给家长",httpMethod = "POST")
    @RequestMapping(value = "/revoke_grant_parent")
    public StatusResponse revokeGrantParent(@RequestHeader(TICKET) String ticket, String evaluateRecordId) {

        String staffId = cache.getStaffId(ticket);

        EvaluateV2Record record = evaluateService.getEvaluateDetail(evaluateRecordId);
        if(record == null){
            throw  new BusinessException(ErrorCode.EVALUATE_RECORD_NOT_EXIST, "报告不存在");
        }

        evaluateService.revokeGrantEvaluateToParent(staffId, record);

        return StatusResponse.success();
    }

    @ApiOperation(value = "支付测评",httpMethod = "POST")
    @RequestMapping(value = "/pay_record")
    public StatusResponse payEvaluateRecord(@RequestHeader(TICKET) String ticket, String evaluateRecordId) {
        String staffId = cache.getStaffId(ticket);

        Staff staff = staffService.getById(staffId);

        if(staffService.isYearsVip(staff)){
            EvaluateV2Record evaluateRecord = evaluateService.payEvaluate(evaluateRecordId);
            return StatusResponse.success(true);
        }else {
            Organization org = staffService.staffOrgnization(staff);
            if(Objects.nonNull(org.getRestCount()) && org.getRestCount() > 0){
                EvaluateV2Record evaluateRecord = evaluateService.payEvaluateWithTimes(evaluateRecordId, org);
                return StatusResponse.success(true);
            }else{
                return StatusResponse.success(true);
//                return StatusResponse.error(ErrorCode.VIP_NEEDED, "需要vip");
            }
        }
    }

    @ApiOperation(value = "提交建议",httpMethod = "POST")
    @RequestMapping(value = "/submit_advise")
    public StatusResponse submitAdvise(@RequestHeader(RequestConstant.TICKET) String ticket, String evaluateRecordId, String advise, Integer infoType, String infoDomainId, String height, String weight, String header) {
        Map map = evaluateService.submitAdvise(cache.getStaffId(ticket), evaluateRecordId, advise, infoType, infoDomainId, height, weight, header);
        return StatusResponse.success(map);
    }

    @ApiOperation(value = "email发送报告",httpMethod = "GET")
    @RequestMapping(value = "/email_report")
    public StatusResponse emailReport(@RequestHeader(RequestConstant.TICKET) String ticket,
                                      String evaluateRecordId,
                                      @RequestHeader(value = APP_CHANNEL, required = false) String channel,
                                      @RequestParam(required = true, defaultValue = "") String mailAddress) {
        String staffId = cache.getStaffId(ticket);

        Map result = exportService.mailReportAsWord(staffId, evaluateRecordId, mailAddress, channel);

        if (result != null){
            //邮件没有出去
            return StatusResponse.of(ErrorCode.EMAIL_ERROR, "邮件服务器出错", result);
        }

        return StatusResponse.success();
    }

    @ApiOperation(value = "将报告上传到oss上并且返回报告的下载地址",httpMethod = "GET")
    @RequestMapping(value = "/upload_report")
    public StatusResponse uploadOssReport(@RequestHeader(RequestConstant.TICKET) String ticket,
                                      String evaluateRecordId,
                                      @RequestHeader(value = APP_CHANNEL, required = false) String channel) {
        String staffId = cache.getStaffId(ticket);

        String result = exportService.uploadReportToOSSAsWord(staffId, evaluateRecordId, channel);

        if (StringUtils.isEmpty(result)){
            //邮件没有出去
            return StatusResponse.of(ErrorCode.UNEXPECTED_ERROR, "上传文件出错", result);
        }

        return StatusResponse.success(result);
    }

    @ApiOperation(value = "分享链接",httpMethod = "GET")
    @RequestMapping(value = "/report_shared_url")
    public StatusResponse sharedUrlOfReport(@RequestHeader(RequestConstant.TICKET) String ticket,
                                            String evaluateRecordId,
                                            @RequestHeader(value = APP_CHANNEL, required = false) String channel) {
        String staffId = cache.getStaffId(ticket);

        EvaluateV2Record evaluateRecord = evaluateService.getEvaluateDetailForStaff(evaluateRecordId,staffId);

        Staff staff = staffService.getById(staffId);

        //for static files
//        String url = exportService.exportEvaluateReportToOSS(evaluateRecordId, staff, EvaluateV2ExportService.ExportType.H5);
        String url = exportShareURLMA + "?id=" + evaluateRecord.getId();
        if ("yyy".equals(channel)){
            url = exportShareURLGuide + "?id=" + evaluateRecord.getId();;
        }

        Map result = new HashMap();

        result.put("url", url);
        result.put("childrenName", evaluateRecord.getChildrenName());
        result.put("month", evaluateRecord.getMonth());
        try {
            String iconName = "basicprofile.png";
            if(StringUtils.isNotEmpty(channel)){
                iconName = String.format("%s_%s", channel, iconName);
            }

            if (!"yyy".equals(channel)){
                String wordURL = exportService.uploadReportToOSSAsWord(staffId, evaluateRecordId, channel);

                if (StringUtils.isEmpty(wordURL)){
                    //邮件没有出去
                    return StatusResponse.of(ErrorCode.UNEXPECTED_ERROR, "上传文件出错", result);
                }

                url = wordURL;
            }

            String base64EncodedQRCodeImg = QrCodeUtils.base64EncodedQRCode(url, iconName, false );
            result.put("qrcode", "data:image/png;base64," + base64EncodedQRCodeImg);

        } catch (Exception e) {
            e.printStackTrace();
            return StatusResponse.error(ErrorCode.ERROR, "预期之外的错误");
        }

        return StatusResponse.success(result);
    }

}
